package com.gitee.feizns.web.domain.result;

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.function.Supplier;

/**
 * @author feizns
 * @since 2019/7/7
 */
@Data
@Accessors(chain = true)
public class Ret<D> {

    public static final String OK = "ok";

    public static final int OK_CODE = 200;

    public static final int INTERNAL_SERVER_ERROR = 500;

    private Integer code;

    private String msg;

    private D data;

    //==========
    //OK
    //==========
    public Ret(D data) {
        this.data = data;
    }

    public static <T> Ret<T> ok() {
        return ok((T) null);
    }

    public static <T> Ret<T> ok(T data) {
        return create(OK_CODE, OK, data);
    }

    public static <T> Ret<T> ok(Supplier<T> supplier) {
        return ok(supplier.get());
    }

    public static Ret<Void> ok(Callback callback) {
        callback.execute();
        return ok();
    }

    //==========
    //ERROR
    //==========
    public static <T> Ret<T> err(Err err) {
        return err(err, null);
    }

    public static <T> Ret<T> err(Err err, T data) {
        return create(err.getCode(), err.getMessage(), data);
    }

    public static <T> Ret<T> err(String msg) {
        return err(INTERNAL_SERVER_ERROR, msg);
    }

    public static <T> Ret<T> err(Integer code, String msg) {
        return create(code, msg, null);
    }

    public static <T> Ret<T> err(Integer code, String msg, T data) {
        return create(code, msg, data);
    }

    //==========
    //CREATE
    //==========
    public Ret(int code, String msg, D data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static <T> Ret<T> create(Integer code, String msg, T data) {
        return new Ret<>(code, msg, data);
    }

}
